package ar.com.spsolutions.splibrary.repositories;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import ar.com.spsolutions.splibrary.author.Author;
import ar.com.spsolutions.splibrary.book.Book;

public class BookRepository extends HibernateGenericDAO<Book> implements GenericRepository<Book> {

    private static final long serialVersionUID = 2129932963266852956L;

    private static final String UNCHECKED = "unchecked";

    private static final String TITLE_PROPERTY = "title";

    public BookRepository() {
        super(Book.class);
    }

    public Book findByISBN(final String isbn) {
        return findByEq("isbn", isbn);
    }

    public Book findByName(final String name) {
        return findByEq("title", name);
    }

    public List<Book> findByAuthor(final Author author) {
        return this.findAllByEq("author", author);
    }

    @SuppressWarnings(BookRepository.UNCHECKED)
    public List<Book> findByTitleLike(final String title) {
        final DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass);
        criteria.add(Restrictions.ilike("title", title, MatchMode.ANYWHERE));
        return getHibernateTemplate().findByCriteria(criteria);
    }

    @SuppressWarnings(BookRepository.UNCHECKED)
    public List<Book> findByISBNLike(final String isbn) {
        final DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass);
        criteria.add(Restrictions.ilike("isbn", isbn, MatchMode.ANYWHERE));
        return getHibernateTemplate().findByCriteria(criteria);
    }

    @SuppressWarnings(BookRepository.UNCHECKED)
    public List<Book> findLoanedTopFive() {
        final DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass);
        criteria.addOrder(Order.desc("timestamp"));
        return getHibernateTemplate().findByCriteria(criteria, 0, 5);
    }

    public int sizeOfSearch(final String searchValue) {
        final DetachedCriteria criteria = createDetachableCriteria();
        criteria.add(Restrictions.ilike(BookRepository.TITLE_PROPERTY, searchValue, MatchMode.ANYWHERE));
        return getHibernateTemplate().findByCriteria(criteria).size();
    }

    @SuppressWarnings(BookRepository.UNCHECKED)
    public List<? extends Book> getResults(final String searchValue, final int first, final int count) {
        final DetachedCriteria criteria = createDetachableCriteria();
        criteria.add(Restrictions.ilike(BookRepository.TITLE_PROPERTY, searchValue, MatchMode.ANYWHERE));
        return getHibernateTemplate().findByCriteria(criteria, first, count);
    }

}
